import { createApp, ref, watch } from "vue";
import types from "./types";
import MessageCom from "./message.vue";
interface OptionsProps {
  duration?: number;
  message: string;
  type: "success" | "warning" | "error" | "message";
}
const messageArr = ref<any>([]);

const Message:any = (options: OptionsProps) => {
  const messageApp = createApp(MessageCom, options as any);
  showMessage(messageApp, options);
};

function showMessage(app: any, options: any) {
  const oel = document.createDocumentFragment();
  const vm = app.mount(oel);
  document.body.appendChild(oel);
  messageArr.value.push(vm);
  setTopVm(vm);
  vm.setVisible(true);

  hideMessage(app, vm, options.duration);
}

watch(messageArr, (nv, ov) => {
  nv.forEach((it: any) => {
    setTopVm(it);
  });
});

function hideMessage(app: any, vm: any, duration: number) {
  vm.timer = setTimeout(async () => {
    await vm.setVisible(false);
    app.unmount();
    messageArr.value = messageArr.value.filter((it: any) => it != vm);
    clearTimeout(vm.timer);
    vm.timer = null;
  }, duration || 3000);
}

function setTopVm(vm: any) {
  const { setTop, height, margin } = vm;
  const currentIndex = messageArr.value.findIndex((item: any) => item == vm);
  setTop(margin * (currentIndex + 1) + height * currentIndex);
}
Object.values(types).forEach((it) => {
  Message[it] = (options: any) => {
    options.type = it;
    return Message(options);
  };
});

export default Message;
